/**	@file functions.h
 *	@brief Mathematical functions.
 *	This file contains some examples of implamentation of mathematical functions. 
 *	These implementations are only examples that describe how to expand functionality of sympy-cpp.
 *	Set of functions is not closed and actual imlementations don't make all possible simplifications. 
 *
 *	@todo 	Implement simplification rules for mathematical functions tangent and cotangent.
 *		Add simplifications rules for sinus, cosinus and natural logarithm. */
#ifndef functions_majdo_
#define functions_majdo_
#include "Fx.h"
namespace sympycpp {
class Expr;
/**	@brief Wrapper function of class that represents sinus.
 * 	This function is directly used by users. It makes particular 
 * 	simplification and also it constructs new expressions.
 * 	@param a is argument of sinus
 *	@see Ex * Sin_(Ex * &, const allocationPolicy) alternative wrapper
 * 	@see class sinus_ representation of sinus */
Expr Sin(const Expr & a);
/**	@brief Wrapper function of class that represents cosinus.
 * 	This function is directly used by users. It makes particular 
 * 	simplification and also it constructs new expressions.
 * 	@param a is argument of cosinus
 *	@see Ex * Cos_(Ex * &, const allocationPolicy) alternative wrapper
 * 	@see class cosinus_ representation of cosinus */
Expr Cos(const Expr &);
/**	@brief Wrapper function of class that represents tangent.
 * 	This function is directly used by users. It makes particular 
 * 	simplification and also it constructs new expressions.
 * 	@param a is argument of tangent 
 *	@see Ex * Tg_(Ex * &, const allocationPolicy) alternative wrapper
 * 	@see class tangent_ representation of tangent */
Expr Tg(const Expr &);
/**	@brief Wrapper function of class that represents cotangent.
 * 	This function is directly used by users. It makes particular 
 * 	simplification and also it constructs new expressions.
 * 	@param a is argument of cotangent
 *	@see Ex * Cotg_(Ex * &, const allocationPolicy) alternative wrapper
 * 	@see class cotangent_ representation of cotangen */
Expr Cotg(const Expr &);
/**	@brief Wrapper function of class that represents natural logarithm.
 * 	This function is directly used by users. It makes particular 
 * 	simplification and also it constructs new expressions.
 * 	@param a is argument of natural logarithm
 *	@see Ex * LN_(Ex * &, const allocationPolicy) alternative wrapper
 * 	@see class ln_ representation of natural logarithm */
Expr Ln(const Expr &);
/**	@brief Wrapper function of class that represents sinus.
 * 	This function is an alternative construction function of sinus. 
 * 	It also makes particular simplification and constructs new expressions.
 * 	This function doesn't return wrapper class Expr, but a pointer to new expression.
 * 	Consequently, this is faster but dangerous.
 * 	@param a is argument of sinus
 * 	@see allocationPolicy : special behaviour of this function
 *	@see Ex * Sin(const Expr &) alternative wrapper
 * 	@see class sinus_ representation of sinus */
Ex * Sin_(Ex * &, const allocationPolicy);
/**	@brief Wrapper function of class that represents cosinus.
 * 	This function is an alternative construction function of cosinus. 
 * 	It also makes particular simplification and constructs new expressions.
 * 	This function doesn't return wrapper class Expr, but a pointer to new expression.
 * 	Consequently, this is faster but dangerous.
 * 	@param a is argument of cosinus
 * 	@see allocationPolicy : special behaviour of this function
 *	@see Ex * Cos(const Expr &) alternative wrapper
 * 	@see class cosinus_ representation of cosinus */
Ex * Cos_(Ex * &, const allocationPolicy);
/**	@brief Wrapper function of class that represents tangent.
 * 	This function is an alternative construction function of tangent. 
 * 	It also makes particular simplification and constructs new expressions.
 * 	This function doesn't return wrapper class Expr, but a pointer to new expression.
 * 	Consequently, this is faster but dangerous.
 * 	@param a is argument of tangent 
 * 	@see allocationPolicy : special behaviour of this function
 *	@see Ex * Tg(const Expr &) alternative wrapper
 * 	@see class tangent_ representation of tangent */
Ex * Tg_(Ex * &, const allocationPolicy);
/**	@brief Wrapper function of class that represents cotangent.
 * 	This function is an alternative construction function of cotangent. 
 * 	It also makes particular simplification and constructs new expressions.
 * 	This function doesn't return wrapper class Expr, but a pointer to new expression.
 * 	Consequently, this is faster but dangerous.
 * 	@param a is argument of cotangent 
 * 	@see allocationPolicy : special behaviour of this function
 *	@see Ex * Cotg(const Expr &) alternative wrapper
 * 	@see class cotangent_ representation of cotangent */
Ex * Cotg_(Ex * &, const allocationPolicy);
/**	@brief Wrapper function of class that represents natural logarithm.
 * 	This function is an alternative construction function of  natural logarithm. 
 * 	It also makes particular simplification and constructs new expressions.
 * 	This function doesn't return wrapper class Expr, but a pointer to new expression.
 * 	Consequently, this is faster but dangerous.
 * 	@param a is argument of  natural logarithm 
 * 	@see allocationPolicy : special behaviour of this function
 *	@see Ex * Ln(const Expr &) alternative wrapper
 * 	@see class ln_ representation of natural logarithm */
Ex * Ln_(Ex * &, const allocationPolicy);
/**	@brief Representation of sinus. */
class sinus_ : public Fx {
public:
	/**	@brief The construction by argument of sinus.
	 * 	@param e is argument of sinus. */
	sinus_(const Expr & e) : Fx(e, "Sin") {}
	/**	@brief The construction by argument of sinus.
	 * 	@param e is argument of sinus. */
	sinus_(const Ex * e) : Fx(e, "Sin") {}
	/**	@brief The construction by argument of sinus.
 	 * 	@see allocationPolicy : special behaviour of this constructor
	 * 	@param e is argument of sinus. 
	 * 	@param ap is a flag of special memory management*/
	sinus_(Ex * & e, const allocationPolicy ap) : Fx( e, "Sin", ap) {} 
	virtual Ex * diff(const Sym &) const;
	virtual Ex * copy() const;
	virtual Ex * create(Ex * & arg, const allocationPolicy) const;
};
/**	@brief representation of cosinus. */
class cosinus_ : public Fx {
public:
	/**	@brief The construction by argument of cosinus.
	 * 	@param e is argument of cosinus. */
	cosinus_(const Expr & e) : Fx(e, "Cos") {}
	/**	@brief The construction by argument of cosinus.
	 * 	@param e is argument of cosinus. */
	cosinus_(const Ex * e) : Fx(e, "Cos") {}
	/**	@brief The construction by argument of cosinus.
 	 * 	@see allocationPolicy : special behaviour of this constructor
	 * 	@param e is argument of cosinus. 
	 * 	@param ap is a flag of special memory management*/
	cosinus_(Ex * & e, const allocationPolicy ap) : Fx(e, "Cos", ap) {}
	virtual Ex * diff(const Sym &)const;
	virtual Ex * create(Ex * & arg, const allocationPolicy) const;
	virtual Ex* copy()const;
};
/**	@brief Representation of tangent. */
class tangent_ : public Fx {
public:
	/**	@brief The construction by argument of tangent.
	 * 	@brief e is argument of tangent. */
	tangent_(const Expr & e) : Fx( e, "Tg") {}
	/**	@brief The construction by argument of tangent.
	 * 	@brief e is argument of tangent. */
	tangent_(const Ex * e) : Fx(e, "Tg") {}
	/**	@brief The construction by argument of tangent.
 	 * 	@see allocationPolicy : special behaviour of this constructor
	 * 	@param e is argument of tangent. 
	 * 	@param ap is a flag of special memory management*/
	tangent_(Ex * & e, const allocationPolicy ap) : Fx(e, "Tg", ap) {} 
	virtual Ex * diff(const Sym & x)const;
	virtual Ex * create(Ex * & arg, const allocationPolicy) const;
	virtual Ex* copy()const;
};
/**	@brief Representation of cotangent. */
class cotangent_ : public Fx {
public:
	/**	@brief The construction by argument of cotangent.
	 * 	@brief e is argument of cotangent. */
	cotangent_(const Expr & e) : Fx(e, "Cotg") {}
	/**	@brief The construction by argument of cotangent.
	 * 	@brief e is argument of cotangent. */
	cotangent_(const Ex * e) : Fx(e, "Cotg") {}
	/**	@brief The construction by argument of cotangent.
 	 * 	@see allocationPolicy : special behaviour of this constructor
	 * 	@param e is argument of cotangent. 
	 * 	@param ap is a flag of special memory management*/
	cotangent_(Ex * & e, const allocationPolicy ap) : Fx(e, "Cotg", ap) {} 
	virtual Ex * diff(const Sym & x)const;
	virtual Ex * create(Ex * & arg, const allocationPolicy) const;
	virtual Ex * copy()const;
};
/**	@brief Representation of  natural logarithm. */
class ln_ : public Fx {
public:
	/**	@brief The construction by argument of natural logarithm.
	 * 	@brief e is argument of natural logarithm. */
	ln_(const Expr & e) : Fx(e, "Ln") {}
	/**	@brief The construction by argument of natural logarithm.
	 * 	@brief e is argument of natural logarithm. */
	ln_(const Ex * e) : Fx(e, "Ln") {}
	/**	@brief The construction by argument of natural logarithm.
 	 * 	@see allocationPolicy : special behaviour of this constructor
	 * 	@param e is argument of natural logarithm. 
	 * 	@param ap is a flag of special memory management*/
	ln_(Ex * & e, const allocationPolicy ap) : Fx(e, "Ln", ap) {} 
	virtual Ex * diff(const Sym & x) const;
	virtual Ex * create(Ex * & arg, const allocationPolicy) const;
	virtual Ex * copy()const;
};
}
#endif
